package com.sokobanboxpro.game.managers;

import com.sokobanboxpro.game.Application;
import com.sokobanboxpro.game.ApplicationState;
import com.sokobanboxpro.game.entity.*;
import com.sokobanboxpro.game.exception.ConfigValueNotFoundException;
import com.sokobanboxpro.game.gameplay.Level;
import com.sokobanboxpro.game.system.Config;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;

/**
 * Графический менеджер.
 *
 * @author Esr
 */
public class GraphicsManager {

		/**
		 * Высота одного блока.
		 */
		private static int heightBlock;
		/**
		 * Ширена одного блока.
		 */
		private static int widthBlock;
		/**
		 * Изображение стены.
		 */
		private static Image wallImage;
		/**
		 * Изображение игрока, смотрящего вверх.
		 */
		private static Image playerImageUp;
		/**
		 * Изображение игрока, смотрящего вниз.
		 */
		private static Image playerImageDown;
		/**
		 * Изображение игрока, смотрящего вправо.
		 */
		private static Image playerImageRight;
		/**
		 * Изображение игрока, смотрящего влево.
		 */
		private static Image playerImageLeft;
		/**
		 * Изображение точки.
		 */
		private static Image pointImage;
		/**
		 * Изображение ящика.
		 */
		private static Image boxImage;
		/**
		 * Изображение ящика помешеного на точку.
		 */
		private static Image boxPointImage;
		/**
		 * Изображение пола.
		 */
		private static Image floorImage;

		/**
		 * Создание.
		 *
		 * @throws ConfigValueNotFoundException Не был найден путь до файла
		 * изображений
		 */
		public static void init() throws ConfigValueNotFoundException {

				try {

						Image fullImage = new Image(Config.toStr("LevelImage"));
						Image playerImage = new Image(Config.toStr("PlayerImage"));

						setHeightBlock(fullImage.getHeight() / 4);
						setWidthBlock(fullImage.getWidth() / 4);

						pointImage = fullImage.getSubImage(getWidthBlock() * 2, getHeightBlock(), getWidthBlock(), getHeightBlock());
						boxImage = fullImage.getSubImage(getWidthBlock(), getHeightBlock(), getWidthBlock(), getHeightBlock());
						boxPointImage = fullImage.getSubImage(getWidthBlock() * 2, getHeightBlock() * 2, getWidthBlock(), getHeightBlock());
						wallImage = fullImage.getSubImage(getWidthBlock(), 0, getWidthBlock(), getHeightBlock());
						floorImage = fullImage.getSubImage(getWidthBlock() * 2, 0, getWidthBlock(), getHeightBlock());

						playerImageLeft = playerImage.getSubImage(0, 0, getWidthBlock(), getHeightBlock());
						playerImageRight = playerImage.getSubImage(0, getHeightBlock(), getWidthBlock(), getHeightBlock());
						playerImageUp = playerImage.getSubImage(0, getHeightBlock() * 2, getWidthBlock(), getHeightBlock());
						playerImageDown = playerImage.getSubImage(0, getHeightBlock() * 3, getWidthBlock(), getHeightBlock());

				} catch (SlickException ex) {
						ex.printStackTrace();
				}

		}

		/**
		 * Прорисовать меню.
		 *
		 * @param gc
		 * @param grphcs
		 */
		public static void renderMenu(GameContainer gc, Graphics grphcs) {

				ImageObj[] images = MenuManager.getCurrentMenu().getImageObj();
				Text[] texts = MenuManager.getCurrentMenu().getText();

				for (ImageObj image : images) {
						image.getImage().draw(image.getX(), image.getY());
				}

				for (Text text : texts) {
						grphcs.drawString(text.toString(), text.getX(), text.getY());
				}

		}

		/**
		 * Прорисовать уровень.
		 *
		 * @param gc
		 * @param grphcs
		 */
		public static void renderLevel(GameContainer gc, Graphics grphcs) {
				
				Level level = ActionGameManager.game.getCurrentLevel();
				
				Camera camera = ActionGameManager.game.getGameplay().getCamera();

				Box[] boxes =level.getBoxes();
				Player player = level.getPlayer();
				Point[] points = level.getPoints();
				Wall[] walls = level.getWalls();
				Floor[] floors = level.getFloors();

				ImageObj[] interfaceImages = ActionGameManager.game.getInterface().getImageObjs();
				Text[] interfaceTexts = ActionGameManager.game.getInterface().getTexts();

				ActionGameManager.game.getGameplay().getBackground().draw(0, 0);
				
				for (Floor floor : floors) {
						floorImage.draw((floor.getX() * getWidthBlock() + camera.getX()) * camera.getZoom(), (floor.getY() * getHeightBlock() + camera.getY()) * camera.getZoom(), camera.getZoom());
				}

				for (Point point : points) {
						pointImage.draw((point.getX() * getWidthBlock() + camera.getX()) * camera.getZoom(), (point.getY() * getHeightBlock() + camera.getY()) * camera.getZoom(), camera.getZoom());
				}
				for (Box box : boxes) {
						if (level.findPointAtPosition(box.getX(), box.getY()) != null) {
								boxPointImage.draw((box.getX() * getWidthBlock() + camera.getX()) * camera.getZoom(), (box.getY() * getHeightBlock() + camera.getY()) * camera.getZoom(), camera.getZoom());
						} else {
								boxImage.draw((box.getX() * getWidthBlock() + camera.getX()) * camera.getZoom(), (box.getY() * getHeightBlock() + camera.getY()) * camera.getZoom(), camera.getZoom());
						}
				}
				for (Wall wall : walls) {
						wallImage.draw((wall.getX() * getWidthBlock() + camera.getX()) * camera.getZoom(), (wall.getY() * getHeightBlock() + camera.getY()) * camera.getZoom(), camera.getZoom());
				}
				switch (player.getDirection()) {

						case DOWN:
								playerImageDown.draw((player.getX() * getWidthBlock() + camera.getX()) * camera.getZoom(), (player.getY() * getHeightBlock() + camera.getY()) * camera.getZoom(), camera.getZoom());
								break;
						case UP:
								playerImageUp.draw((player.getX() * getWidthBlock() + camera.getX()) * camera.getZoom(), (player.getY() * getHeightBlock() + camera.getY()) * camera.getZoom(), camera.getZoom());
								break;
						case LEFT:
								playerImageLeft.draw((player.getX() * getWidthBlock() + camera.getX()) * camera.getZoom(), (player.getY() * getHeightBlock() + camera.getY()) * camera.getZoom(), camera.getZoom());
								break;
						case RIGHT:
								playerImageRight.draw((player.getX() * getWidthBlock() + camera.getX()) * camera.getZoom(), (player.getY() * getHeightBlock() + camera.getY()) * camera.getZoom(), camera.getZoom());
								break;

				}


				for (ImageObj image : interfaceImages) {
						image.getImage().draw(image.getX(), image.getY());
				}

				for (Text text : interfaceTexts) {
						grphcs.drawString(text.toString(), text.getX(), text.getY());
				}

		}

		/**
		 * Перерисовать картику.
		 *
		 * @param gc
		 * @param grphcs
		 */
		public static void render(GameContainer gc, Graphics grphcs) {

				if (Application.getApplicationState() == ApplicationState.MENU) {
						renderMenu(gc, grphcs);
				} else {
						renderLevel(gc, grphcs);
				}

		}

		/**
		 * Получить размер блока по вертикали.
		 * @return Размер блока по вертикали
		 */
		public static int getHeightBlock() {
				return heightBlock;
		}
		
		/**
		 * Устанорвить размер блока по вертикали.
		 * @param aHeightBlock Размер блока по вертикали
		 */
		public static void setHeightBlock(int aHeightBlock) {
				heightBlock = aHeightBlock;
		}

		/**
		 * размер блока по горизонтали.
		 * @return Размер блока по горизонтали
		 */
		public static int getWidthBlock() {
				return widthBlock;
		}

		/**
		 * Устанорвить размер блока по горизонтали.
		 * @param aWidthBlock Размер блока по горизонтали
		 */
		public static void setWidthBlock(int aWidthBlock) {
				widthBlock = aWidthBlock;
		}

}
